package flyweight

import "fmt"

var teslaUnitFactory *TeslaUnitFactory

func init() {
	teslaUnitFactory = NewTeslaUnitFactory()
}

type TeslaUnit struct {
	color   string
	model   string
	screen  string
	battery string
}

func NewTeslaUnit(color, model, screen, battery string) *TeslaUnit {
	return &TeslaUnit{
		color:   color,
		model:   model,
		screen:  screen,
		battery: battery,
	}
}

type TeslaUnitFactory struct {
	cache map[string]*TeslaUnit
}

func NewTeslaUnitFactory() *TeslaUnitFactory {
	cache := map[string]*TeslaUnit{}
	cache[fmt.Sprintf("%s-%s-%s-%s", "灰", "model3", "big", "宁德时代")] =
		NewTeslaUnit("灰", "model3", "big", "宁德时代")
	cache[fmt.Sprintf("%s-%s-%s-%s", "灰", "model3", "big", "蜂巢")] =
		NewTeslaUnit("灰", "model3", "big", "蜂巢")
	cache[fmt.Sprintf("%s-%s-%s-%s", "灰", "model3", "small", "宁德时代")] =
		NewTeslaUnit("灰", "model3", "small", "宁德时代")
	cache[fmt.Sprintf("%s-%s-%s-%s", "灰", "model3", "small", "蜂巢")] =
		NewTeslaUnit("灰", "model3", "small", "蜂巢")

	return &TeslaUnitFactory{cache: cache}
}

func (f *TeslaUnitFactory) Create(key string) *TeslaUnit {
	return f.cache[key]
}

type Tesla struct {
	Vin  string
	unit *TeslaUnit
}

func NewTesla(vin, color, model, screen, battery string) *Tesla {
	unit := teslaUnitFactory.Create(fmt.Sprintf("%s-%s-%s-%s", color, model, screen, battery))
	return &Tesla{
		Vin:  vin,
		unit: unit,
	}
}
